﻿using System;
using System.Drawing;

namespace ClockwiseClient
{
    public class ClassGraphFenxi : ClassGraph
    {
        const int widthTitle = 256;
        int mode = 0;

        readonly string[] labels = new string[] 
            {"卖五","卖四","卖三","卖二","卖一","买一","买二","买三","买四","买五","现价","现量",
            "昨收","涨跌","涨幅","振幅","最高","最低","开盘","均价","涨停","跌停","总量","金额"};

        public override void Paint(Graphics g, Rectangle rect)
        {
            this.rect = rect;
            if (format.LineAlignment != StringAlignment.Center) format.LineAlignment = StringAlignment.Center;
            if (format.Alignment != StringAlignment.Center) format.Alignment = StringAlignment.Center;
            String tips = "显示区域太小了";
            stringSize = g.MeasureString(tips, font);
            if (rect.Width < 640 || rect.Height < 480)
            {
                if (stringSize.Width > rect.Width)
                {
                    tips = "太小了";
                    stringSize = g.MeasureString(tips, font);
                }
                if (stringSize.Width > rect.Width || stringSize.Height > rect.Height) return;
                PointF pointF = new PointF(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2 + stringSize.Height / 10);
                g.DrawString(tips, font, Brushes.Cyan, pointF, format);
                return;
            }
            ShowFenxi(g, rect);
        }

        public override EnumGraph GetGraphType() { return EnumGraph.GRAPH_FENXI; }

        public override int GetGraphMode()
        {
            return mode;
        }
        public override void SetGraphMode(int mode)
        {
            this.mode = mode;
        }

        void ShowFenxi(Graphics g, Rectangle rect)
        {
            ClassStockData classStockData = (ClassStockData)ClassStock.GetInstance();
            int idx = classStockData.boardStockIdx;
            if (idx < 0)
            {
                ClassFilter classFilter = classStockData.GetFilter();
                idx = classStockData.focusStockIdx;
                if (classFilter != null) idx = classFilter.GetIndex(idx);
            }
            ClassStockItem si = classStockData.GetClassStockItem(idx);
            if (si == null) return;
            if(me == null || !me.symbol.Equals(si.symbol))
            {
                int market = si.symbol.StartsWith("sh") ? 0 : 1;
                classStockData.LoadStockTick(market, si.code);
            }
            me = si;
            string text;
            SizeF textSize;
            PointF pointF;
            if (si != null)
            {
                text = si.code;
                textSize = g.MeasureString(text, fontTitle2);
                format.Alignment = StringAlignment.Near;
                int left = rect.Right - widthTitle;
                pointF = new PointF(left, rect.Top + textSize.Height / 2 + textSize.Height / 10);
                g.DrawString(text, fontTitle2, Brushes.Cyan, pointF, format);
                left += (int) textSize.Width;
                text = si.name;
                textSize = g.MeasureString(text, fontTitle2);
                pointF = new PointF(left, rect.Top + textSize.Height / 2 + textSize.Height / 10);
                g.DrawString(text, fontTitle2, classStockData.ZixuanguInclude(si.symbol) ? Brushes.Magenta : Brushes.Yellow, pointF, format);

                Pen pen = new Pen(Color.Red, 1);
                left = rect.Right - widthTitle - 16;
                int row = (int) textSize.Height + 8;
                g.DrawLine(pen, left, row, rect.Right, row);
                g.DrawLine(pen, left, row, left, rect.Bottom);

                row += 2;
                int i, j, lineHeight = 0;
                Brush color = null;
                for (i = 0; i < 10; i++)
                {
                    text = labels[i];
                    textSize = g.MeasureString(text, font);
                    left = rect.Right - widthTitle - 14;
                    pointF = new PointF(left, row + textSize.Height / 2 + textSize.Height / 10);
                    g.DrawString(text, font, Brushes.Gray, pointF, format);
                    if (lineHeight == 0) lineHeight = (int) textSize.Height;
                    switch(i)
                    {
                        case 0: text = si.f_sell5.ToString("f2"); color = ClassStock.CalcColor(si.f_sell5, si.f_preclose); break;
                        case 1: text = si.f_sell4.ToString("f2"); color = ClassStock.CalcColor(si.f_sell4, si.f_preclose); break;
                        case 2: text = si.f_sell3.ToString("f2"); color = ClassStock.CalcColor(si.f_sell3, si.f_preclose); break;
                        case 3: text = si.f_sell2.ToString("f2"); color = ClassStock.CalcColor(si.f_sell2, si.f_preclose); break;
                        case 4: text = si.f_sell.ToString("f2"); color = ClassStock.CalcColor(si.f_sell, si.f_preclose); break;
                        case 5: text = si.f_buy.ToString("f2"); color = ClassStock.CalcColor(si.f_buy, si.f_preclose); break;
                        case 6: text = si.f_buy2.ToString("f2"); color = ClassStock.CalcColor(si.f_buy2, si.f_preclose); break;
                        case 7: text = si.f_buy3.ToString("f2"); color = ClassStock.CalcColor(si.f_buy3, si.f_preclose); break;
                        case 8: text = si.f_buy4.ToString("f2"); color = ClassStock.CalcColor(si.f_buy4, si.f_preclose); break;
                        case 9: text = si.f_buy5.ToString("f2"); color = ClassStock.CalcColor(si.f_buy5, si.f_preclose); break;
                    }
                    textSize = g.MeasureString(text, font);
                    left = (int)(rect.Right - (widthTitle / 2) - textSize.Width - 2);
                    pointF = new PointF(left, row + textSize.Height / 2 + textSize.Height / 10);
                    g.DrawString(text, font, color, pointF, format);
                    switch(i)
                    {
                        case 0: text = si.f_sell5.ToString("f0"); break;
                        case 1: text = si.f_sell4.ToString("f0"); break;
                        case 2: text = si.f_sell3.ToString("f0"); break;
                        case 3: text = si.f_sell2.ToString("f0"); break;
                        case 4: text = si.f_sell.ToString("f0"); break;
                        case 5: text = si.f_buy.ToString("f0"); break;
                        case 6: text = si.f_buy2.ToString("f0"); break;
                        case 7: text = si.f_buy3.ToString("f0"); break;
                        case 8: text = si.f_buy4.ToString("f0"); break;
                        case 9: text = si.f_buy5.ToString("f0"); break;
                    }
                    textSize = g.MeasureString(text, font);
                    left = (int) (rect.Right - textSize.Width - 4);
                    pointF = new PointF(left, row + textSize.Height / 2 + textSize.Height / 10);
                    g.DrawString(text, font, Brushes.Yellow, pointF, format);
                    row += lineHeight + 2;
                    if (i == 4 || i == 9)
                    {
                        left = rect.Right - widthTitle - 16;
                        g.DrawLine(pen, left, row, rect.Right, row);
                        row += 2;
                    }
                }
                float pjj = si.f_volume > 0 ? si.f_amount / si.f_volume / 100 : si.f_preclose;
                float ztj = si.f_preclose;
                float dtj = si.f_preclose;
                if(si.name.IndexOf("ST") < 0)
                {
                    ztj *= 1.1f;
                    dtj *= 0.9f;
                } else
                {
                    ztj *= 1.05f;
                    dtj *= 0.95f;
                }
                for (i = 0; i < 7; i++)
                {
                    for (j = 0; j < 2; j++)
                    {
                        text = labels[i * 2 + j + 10];
                        textSize = g.MeasureString(text, font);
                        left = rect.Right - widthTitle - 14;
                        pointF = new PointF(left + (j==0 ? 0 : (rect.Right - left) / 2) + 2, row + textSize.Height / 2 + textSize.Height / 10);
                        g.DrawString(text, font, Brushes.Gray, pointF, format);
                        switch(i*2+j)
                        {
                            case 0: text = si.f_price.ToString("f2"); color = ClassStock.CalcColor(si.f_price, si.f_preclose); break;
                            case 1: text = ClassStock.VolumeFormat(si.f_delta); color = Brushes.BlueViolet; break;
                            case 2: text = si.f_preclose.ToString("f2"); color = Brushes.White; break;
                            case 3: text = si.f_diff.ToString("f2"); color = ClassStock.CalcColor(si.f_price, si.f_preclose); break;
                            case 4: text = si.f_change.ToString("f2") + "%"; color = ClassStock.CalcColor(si.f_price, si.f_preclose); break;
                            case 5: text = si.f_amplitude.ToString("f2") + "%"; color = Brushes.White; break;
                            case 6: text = si.f_high.ToString("f2"); color = ClassStock.CalcColor(si.f_high, si.f_preclose); break;
                            case 7: text = si.f_low.ToString("f2"); color = ClassStock.CalcColor(si.f_low, si.f_preclose); break;
                            case 8: text = si.f_open.ToString("f2"); color = ClassStock.CalcColor(si.f_open, si.f_preclose); break;
                            case 9: text = pjj.ToString("f2"); color = ClassStock.CalcColor(pjj, si.f_preclose); break;
                            case 10: text = ztj.ToString("f2"); color = ClassStock.CalcColor(ztj, si.f_preclose); break;
                            case 11: text = dtj.ToString("f2"); color = ClassStock.CalcColor(dtj, si.f_preclose); break;
                            case 12: text = ClassStock.VolumeFormat(si.f_volume); color = Brushes.Yellow; break;
                            case 13: text = ClassStock.AmountFormat(si.f_amount); color = Brushes.Cyan; break;
                        }
                        textSize = g.MeasureString(text, font);
                        if (j==0)
                        {
                            left = (int)(rect.Right - (widthTitle / 2) - textSize.Width - 2);
                        }
                        else
                        {
                            left = (int)(rect.Right - textSize.Width - 2);
                        }
                        pointF = new PointF(left, row + textSize.Height / 2 + textSize.Height / 10);
                        g.DrawString(text, font, color, pointF, format);
                    }
                    row += lineHeight + 2;
                }
                left = rect.Right - widthTitle - 16;
                g.DrawLine(pen, left, row, rect.Right, row);
                ClassStockTick classStockTick = classStockData.LoadStockTick(0);
                if(classStockTick != null)
                {
                    int tickCount = classStockTick.GetTickCount();
                    int lineCount = (rect.Bottom - row) / (lineHeight + 2);
                    int start = tickCount <= lineCount ? 0 : tickCount - lineCount;
                    for(i=0; i<lineCount; i++)
                    {
                        ClassStockTick.StockTickItem item = classStockTick.GetTickItem(i + start);
                        if (item == null) continue;
                        int h = (int)(item.time/10000);
                        int m = (int)((item.time / 100) % 100);
                        text = h.ToString("00") + ":" + m.ToString("00");
                        textSize = g.MeasureString(text, font);
                        left = rect.Right - widthTitle - 14;
                        pointF = new PointF(left + 2, row + textSize.Height / 2 + textSize.Height / 10);
                        g.DrawString(text, font, Brushes.Gray, pointF, format);
                        text = item.price.ToString("f2");
                        textSize = g.MeasureString(text, font);
                        left = (int)(rect.Right - (widthTitle / 2) - textSize.Width - 2);
                        pointF = new PointF(left + 2, row + textSize.Height / 2 + textSize.Height / 10);
                        g.DrawString(text, font, ClassStock.CalcColor(item.price, me.f_preclose), pointF, format);
                        text = item.delta.ToString("f0");
                        textSize = g.MeasureString(text, font);
                        left = (int)(rect.Right - textSize.Width - 4);
                        pointF = new PointF(left, row + textSize.Height / 2 + textSize.Height / 10);
                        g.DrawString(text, font, Brushes.Yellow, pointF, format);
                        row += lineHeight + 2;
                    }
                }
                Rectangle zstRect = new Rectangle(rect.Left + 10, rect.Top + 10, rect.Width - widthTitle - 36, rect.Height - 20);
                if(mode == 1)
                {
                    ClassDrawGraph.drawZoushitu(g, zstRect, si, classStockTick, false);
                }
                else
                if (mode == 2)
                {
                    ClassStockDays classStockDays = classStockData.findStockDays(si.symbol);
                    ClassDrawGraph.drawKxiantu(g, zstRect, si, classStockDays, false);
                }
                classStockData.AddToHistory(me.symbol);
            }
        }

        public override void MouseWheel(int delta)
        {
            ClassStockData classStockData = (ClassStockData)ClassStock.GetInstance();
            int idx = classStockData.boardStockIdx;
            if (idx >= 0)
            {
                if (delta < 0)
                {
                    if (idx < classStockData.GetCount() - 1) idx++; else idx = 0;
                }
                else
                {
                    if (idx > 0) idx--; else idx = classStockData.GetCount() - 1;
                }
                classStockData.boardStockIdx = idx;
                return;
            }
            ClassFilter classFilter = classStockData.GetFilter();
            idx = classStockData.focusStockIdx;
            if (delta < 0)
            {
                if (idx < classFilter.GetCount() - 1) idx++; else idx = 0;
            }
            else
            {
                if (idx > 0) idx--; else idx = classFilter.GetCount() - 1;
            }
            classStockData.focusStockIdx = idx;
        }
    }
}
